package gui;

import model.msg;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.BlockingQueue;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;

import model.BoxOfficeState;

//import kontroler.msg;

/**
 * Panel z przyciskami dla użytkownika.
*/ 
class UserPane extends JPanel {
	private static final long serialVersionUID = 1L;
	
	/** kolejka do wysyłania informacji z widoku do kontrolera */
	 private static BlockingQueue<model.msg> queue = null;
	/** Przyciski panelu do komunikowania sie symulacji z uzytkownikiem.*/
	private JButton buttonMan, buttonAut, buttonStart, buttonStop, buttonAddClient, buttonNext;
	private JTextField close, open, increase, decrease, incVal, decVal;
	private JLabel lclose, lopen, lincrease, ldecrease;
	/** Obiekty graficzne reprezentujace przyciski aktywne i nieaktywne.*/
 	private ImageIcon man, aut, start, stop, add, next;
 	
 	private boolean isStarted;
    private boolean isHalted;
    private boolean isNext;
    private SimuMode mode;
    private int nowiKlienci;
    private int minPK;
    private int maxPK; 
    private int minOK; 
    private int maxOK; 
    private int minOTWK; 
    private int maxOTWK;
    private int minZAMK;
    private int maxZAMK;
    private BoxOfficeState[] stany;
 	/**
 	 * Konstruktor panelu. Ustawia rozmieszczenie przyciskow, tlo.
 	 */
 	public UserPane(BlockingQueue<model.msg> blockingQueue){
 		
 		queue = blockingQueue;
 		
        this.mode = SimuMode.AUTOMATIC;
        this.isStarted = false;
        this.isHalted = false;
        this.isNext = false;
        this.nowiKlienci = 0;
        this.minPK = 0;
        this.maxPK = 0;
        this.minOK = 0;
        this.maxOK = 0;
        this.minOTWK = 0;
        this.maxOTWK = 0;
        this.minZAMK = 0;
        this.maxZAMK = 0;
        this.stany = new BoxOfficeState[10];
        for(int i = 0; i<10; i++){
        	this.stany[i] = BoxOfficeState.OPEN;
        }

 		//Ustawia layout panelu.
 		this.setLayout(new GridLayout(2,5));
 		Border pancakes = BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "User Panel");
 		setBorder(pancakes);
 		
 		// Ustawia tło panelu.
 		setBackground(Color.LIGHT_GRAY);
 		
 		//Kladzie przyciski
 		loadButtonImages();
 		putButtons();
 	
 	}
 	
 	/**
 	 * Ładuje obrazki dla przyciskow.
 	 */
 	private void loadButtonImages()
 	{
 		/*start = new ImageIcon("images\\start.jpg");
 		stop = new ImageIcon("images\\stop.png");
 		man = new ImageIcon("images\\man.png");
 		aut = new ImageIcon("images\\aut.jpg");
 		add = new ImageIcon("images\\add.jpg");
 		//closeIc = new ImageIcon("images\\open.png");
 		//openIc = new ImageIcon("images\\close.png");
 		next = new ImageIcon("images\\next.gif");
 		*/
 	}
 	
 	/**
 	 * Kladzie przyciski na panelu, ustawia obrazki przyciskow oraz zdarzenia przyciskow.
 	 */
 	private void putButtons()
 	{
 		
 		buttonStart = new JButton("Start");
 		//buttonStart.setIcon((Icon)start);
 		buttonStart.addActionListener(new StartListener());
 		this.add(buttonStart);
 		
 		buttonStop = new JButton("Stop");
 		//buttonStop.setIcon((Icon)stop);
 		buttonStop.addActionListener(new StopListener());
 		this.add(buttonStop);
 		
 		buttonMan = new JButton("Manual");
 		//buttonMan.setIcon((Icon)man);
 		buttonMan.addActionListener(new ManListener());
 		this.add(buttonMan);
 		
 		buttonAut = new JButton("Automatic");
 		//buttonAut.setIcon((Icon)aut);
 		buttonAut.addActionListener(new AutListener());
 		this.add(buttonAut);
 		
 		buttonAddClient = new JButton("Add Client");
 		//buttonAddClient.setIcon((Icon)add);
 		buttonAddClient.addActionListener(new AddListener());
 		this.add(buttonAddClient);
 		
 		lclose = new JLabel("Zamknij kasę");
 		this.add(lclose);
 		close = new JTextField("1");
 		close.addActionListener(new CloseListener());
 		this.add(close);
 		
 		lopen = new JLabel("Otwórz kasę");
 		this.add(lopen);
 		open = new JTextField("1");
 		open.addActionListener(new OpenListener());
 		this.add(open);
 		
 		lincrease = new JLabel("Zwiększ minimum(1)/maksimum(2) dla 1)PK 2)OK 3)OTWK 4)ZAMK");
 		this.add(lincrease);
 		increase = new JTextField("1 1 6");
 		//increase.addActionListener(new IncreaseListener());
 		this.add(increase);
 		//incVal = new JTextField ("6");
 		//incVal.addActionListener(new IncValListener());
 		//this.add(incVal);
 		
 		ldecrease = new JLabel("Zmniejsz minimum(1)/maksimum(2) dla 1)PK 2)OK 3)OTWK 4)ZAMK");
 		this.add(ldecrease);
 		decrease = new JTextField("1 1 20");
 		//decrease.addActionListener(new DecreaseListener());
 		this.add(decrease);
 		//incVal = new JTextField ("6");
 		//incVal.addActionListener(new IncValListener());
 		//this.add(incVal);
 		
 		
 		buttonNext = new JButton("Next step");
 		//buttonNext.setIcon((Icon)next);
 		buttonNext.addActionListener(new NextListener());
 		this.add(buttonNext);
 		
 		
 		JButton [] tableOfDisabled = {buttonAddClient, buttonNext, buttonAut};
 		JTextField [] tableOfDisabledFields = {close, open, increase, decrease};
 		setDisabled(tableOfDisabled, tableOfDisabledFields);
 	}
 	
 	/**
 	 * Aktywuje wybraną grupę przycisków.
 	 * @param buttonTable Grupa aktywowanych przycisków.
 	 */
 	public void setEnabled(final JButton [] buttonTable, final JTextField [] fieldTable){
 		
 		SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
            	int size = buttonTable.length;
         		for(int i = 0; i< size; i++)
         			buttonTable[i].setEnabled(true);
         		
         		int siz = buttonTable.length;
         		for(int i = 0; i< siz; i++)
         			fieldTable[i].setEnabled(true);
            }
        });
 	
 	}
 	
 	/**
 	 * Dezaktywuje wybraną grupe przycisków.
 	 * @param buttonTable Grupa dezaktywowanych przycisków.
 	 * @param disabledIconTable Ikony dezaktywowanych przycisków.
 	 */
 	public void setDisabled(final JButton [] buttonTable, final ImageIcon [] disabledIconTable, final JTextField [] fieldTable)
 	{
 		SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
            	int size = buttonTable.length;
         		for(int i = 0; i< size; i++)
         		{
         			buttonTable[i].setEnabled(false);
         			buttonTable[i].setDisabledIcon((Icon)disabledIconTable[i]);
         		}
         		
         		int siz = fieldTable.length;
         		for(int i = 0; i< siz; i++)
         			fieldTable[i].setEnabled(false);
         		
            }
        });
 		
 		
 	}
 	
 	public void setDisabled(final JButton [] buttonTable, final JTextField [] fieldTable)
 	{
 		SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
            	int size = buttonTable.length;
         		for(int i = 0; i< size; i++)
         			buttonTable[i].setEnabled(false);
         		
         		int siz = fieldTable.length;
         		for(int i = 0; i< siz; i++)
         			fieldTable[i].setEnabled(false);
            }
        });
 		
 		
 	}
 	
 	/**
 	 * Aktywuje grupe odpowiednich przyciskow, a dezaktywuje inne w zaleznosci od trybu symulacji. 
 	 * @param mode Aktualny tryb symulacji.
 	 */
 	public void setUserPanel(final SimuMode mode)
 	{
 		switch(mode)
 		{
 		case MANUAL:
 		
	 		JButton [] tableOfEnabled = {buttonAut, buttonStop, buttonAddClient, buttonNext};
	 		JTextField [] tableOfEnabledFields = {close, open, increase, decrease, incVal, decVal};
	 		setEnabled(tableOfEnabled, tableOfEnabledFields);
	 		JButton [] tableOfDisabled = {buttonMan, buttonStart};
	 		JTextField [] tableOfDisabledFields ={};
	 		ImageIcon [] tableOfIconDisabled = {man, start};
	 		setDisabled(tableOfDisabled, tableOfIconDisabled, tableOfDisabledFields);
 		break;
 	
 		case AUTOMATIC:
 		
 			JButton [] tableOfEnabled2 = {buttonMan, buttonStop};
 			JTextField [] tableOfEnabledFields2 = {increase, decrease, incVal, decVal};
 			JButton [] tableOfDisabled2 = {buttonAut, buttonStart, buttonAddClient, buttonNext};
	 		ImageIcon [] tableOfIconDisabled2 = {aut, start, add};
	 		JTextField [] tableOfDisabledFields2 = {open, close};
	 		setEnabled(tableOfEnabled2, tableOfEnabledFields2);
	 		setDisabled(tableOfDisabled2, tableOfIconDisabled2, tableOfDisabledFields2);
	 		
 		break;
 		}
 }
 	
 	/**
      * Klasa nasłuchiwacza zdarzenia nowej symulacji. 
      */
     private class StartListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 try 
             {
            	 isStarted = true;
            	 queue.put(new msg("3", "1",isStarted,isHalted, isNext,mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     
     /**
      * Klasa nasłuchiwacza zdarzenia zatrzymania symulacji. 
      */
     private class StopListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 try 
             {
        		 isHalted = false;
        		 queue.put(new msg("3", "1",isStarted,isHalted, isNext, mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     /**
      * Klasa nasłuchiwacza zdarzenia zmiany trybu na ręczny. 
      */
     private class ManListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 try 
        	 
             {
            	 mode = SimuMode.MANUAL;
        		 queue.put(new msg("3", "1",isStarted,isHalted, isNext, mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     /**
      * Klasa nasłuchiwacza zdarzenia zmiany trybu na automatyczny. 
      */
     private class AutListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 try 
             {
        		 mode = SimuMode.AUTOMATIC;
        		 queue.put(new msg("3", "1",isStarted,isHalted, isNext, mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     
     /**
      * Klasa nasłuchiwacza zdarzenia dodania nowego klienta. 
      */
     private class AddListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 try 
             {
            	 nowiKlienci++;
            	 queue.put(new msg("3", "1",isStarted,isHalted, isNext, mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     /**
      * Klasa nasłuchiwacza zdarzenia zamknięcia kasy. 
      */
     private class CloseListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 int val = Integer.parseInt(close.getText());
        	 try 
             {
        		 stany[val] = BoxOfficeState.CLOSING;
            	 queue.put(new msg("3", "1",isStarted,isHalted, isNext, mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     /**
      * Klasa nasłuchiwacza zdarzenia otwarcia kasy. 
      */
     private class OpenListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 int val = Integer.parseInt(open.getText());
        	 try 
             {
        		 stany[val] = BoxOfficeState.OPEN;
            	 queue.put(new msg("3", "1",isStarted,isHalted, isNext, mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     /**
      * Klasa nasłuchiwacza zdarzenia następnego kroku symulacji. 
      */
     private class NextListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 try 
             {
        		 isNext = true;
            	 queue.put(new msg("3", "1",isStarted,isHalted, isNext,mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     /**
      * Klasa nasłuchiwacza zdarzenia zwiększenia min/maks. 
      */
     private class IncreaseListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 String command = event.getActionCommand();
        	 int what = Integer.parseInt(command.substring(0));
        	 int whose = Integer.parseInt(command.substring(2));
        	 int val = Integer.parseInt(command.substring(4));
        	 try 
             {
        		 switch(what){
        		 //co zwiekszamy - 1-minimun, 2-maksimum
        		 case 1:
        			 
        		 }
        		 isNext = true;
            	 queue.put(new msg("3", "1",isStarted,isHalted, isNext,mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     /**
      * Klasa nasłuchiwacza zdarzenia zwiększenia min/maks. 
      */
     private class DecreaseListener implements ActionListener
     {
         public void actionPerformed(ActionEvent event)
         {
        	 //String str = event.getActionCommand()
        	 try 
             {
        		 isNext = true;
            	 queue.put(new msg("3", "1",isStarted,isHalted, isNext,mode,nowiKlienci, minPK, maxPK, minOK, maxOK, minOTWK, maxOTWK,minZAMK, maxZAMK, stany));
             }
             catch(InterruptedException exception)
             {
             	exception.printStackTrace();
             }
         }
     }
     
     
 }
 

